#ifndef COMMON_H
#define COMMON_H

#include <cstddef> // size_t
#include <atomic>
#include <array>

namespace MemoryPool
{
    // 大小管理
    class SizeManager
    {
    public:
        // 注意：constexpr编译时已知，必须static
        static constexpr size_t MAX_ALLOC_BYTES = 256 * 1024; // 对ThreadCache最大申请数，256KB
        static constexpr size_t ALIGNMENT_BYTES = 8;          // 对齐数，指针void*的大小一般是8
        // 按对齐单位指定的空闲链表的数量，也可以是别的数量，空闲链表的节点数不定
        static constexpr size_t FREE_LIST_NUM = MAX_ALLOC_BYTES / ALIGNMENT_BYTES;

        // 将需要的内存大小转换为下层rangeIndex
        // 实际上是本层或下层的rangeIndex，这里屏蔽细节不这样命名

        // 如需要5B，则补齐到8B

        // 如果 needSize / ALIGNMENT_BYTES = 9 / 8 = 1
        // 1 * 8 < 9，分配的不够
        // 如果 (needSize + ALIGNMENT_BYTES - 1) / ALIGNMENT_BYTES = (9 + 8 - 1) / 8 = 2
        // 2 * 8 >= 9，分配的足够
        // 所以：+ ALIGNMENT_BYTES是为了下取整除法分配足够，- 1是为了不至于多分配一个
        // 也可以：needSize / ALIGNMENT_BYTES + 1，有余数才+1，否则不+1

        // 上取整-1从数量对应到索引
        static size_t sizeToIndex(size_t needSize)
        {
            // 确保bytes至少为ALIGNMENT
            needSize = std::max(needSize, ALIGNMENT_BYTES);
            // 向上取整后-1
            return (needSize + ALIGNMENT_BYTES - 1) / ALIGNMENT_BYTES - 1;
        }

        // 上取整对齐字节
        // + ALIGNMENT_BYTES：达到或超过下一个对齐边界
        // -1：不会多一个对齐边界
        // 5 + 8 - 1 = 12
        // ~(ALIGNMENT_BYTES - 1)：生成掩码清除低位实现对齐
        // 8 - 1 = 7 = 0000 0111->1111 1000
        // 12 = 0000 1100 & 1111 1000 = 0000 1000 = 8，即5对齐到8
        static size_t roundUp(const size_t bytes)
        {
            return (bytes + ALIGNMENT_BYTES - 1) & ~(ALIGNMENT_BYTES - 1);
        }
    };

    // // 内存块头部信息
    // struct BlockHeader
    // {
    //     size_t size;       // 内存块大小
    //     bool inUse;        // 使用标志
    //     BlockHeader *next; // 指向下一个内存块
    // };
} // namespace MemoryPool

#endif